#include <REGX52.H>

sbit OneWire_DQ=P3^7;

/**
  * @brief  单总线初始化
  * @param  无
  * @retval 从机响应位，0为响应，1为未响应
  */
unsigned char OneWire_Init(void)//初始化（复位+响应）
{
	unsigned char i;
	unsigned char AckBit;
	EA=0;//把中断关闭，避免定时器对下面的延时函数（单总线函数的延时不能被打断）产生影响
	//但是屏蔽中断导致按键中断不好用
	OneWire_DQ=1;
	OneWire_DQ=0;
	i = 227;
	while (--i);//Delay 500us
	OneWire_DQ=1;//释放总线
	i = 29;
	while (--i);//Delay 70us
	AckBit=OneWire_DQ;//70us后一定在从机响应阶段，判断从机是否应答
	i = 227;
	while (--i);//Delay 500us，把时序走完
	EA=1;
	return AckBit;
}

/**
  * @brief  单总线发送一位
  * @param  Bit 要发送的位
  * @retval 无
  */
void OneWire_SendBit(unsigned char Bit)
{
	unsigned char i;
	EA=0;
	OneWire_DQ=0;
	i = 4;
	while (--i);//Delay 10us,总共Delay 15us,但10才是真正的延时时间(Delay 10us是在这个时候操作，不是采样，采样是在15us后的区间),
	//11.0592hz调用一个函数是5us
	//这里想要延时10us，加起来15us
	//一个_nop_一微妙
	OneWire_DQ=Bit;
	i = 22;
	while (--i);//Delay 50us,总共Delay 55us,因为调用函数要5us
	EA=1;
	OneWire_DQ=1;
}

/**
  * @brief  单总线接收一位
  * @param  无
  * @retval 读取的位
  */
unsigned char OneWire_ReceiveBit(void)
{
	unsigned char i;
	unsigned char Bit;//主机的Bit
	EA=0;
	OneWire_DQ=0;
	i = 2;
	while (--i);//Delay 5us,总共Delay10us
	OneWire_DQ=1;
	i = 2;
	while (--i);//Delay 5us,总共Delay10us
	//隔开延时是因为总线有个恢复时间，如果释放后立马读，主机可能还没来得及变1
	Bit=OneWire_DQ;//采样
	i = 22;
	while (--i);//Delay 50us,总共Delay 55us
	//5+5+50=60us
	EA=1;
	return Bit;
}


/**
  * @brief  单总线发送一个字节
  * @param  Byte 要发送的字节
  * @retval 无
  */
void OneWire_SendByte(unsigned char Byte)//低位在前
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		OneWire_SendBit(Byte&(0x01)<<i);
	}
}

/**
  * @brief  单总线接收一个字节
  * @param  无
  * @retval 接收的一个字节
  */
unsigned char OneWire_ReceiveByte(void)
{
	unsigned char i;
	unsigned char Byte=0x00;
	for(i=0;i<8;i++)
	{
		if(OneWire_ReceiveBit()){Byte|=(0x01<<i);}
	}
	return Byte;
}